
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;

import java.math.BigInteger;
import java.security.*;

/**
 * MD5加密工具类
 * MD5加密是单向不可逆的，无法被解密
 * BCyptPasswordEncoder是双向加密的，可逆的，课解密
 */

@Slf4j
public class MD5CLASS {


    public static String md5(String text){
        if(StringUtils.isNotEmpty(text)){
            byte[] bytes=null ;
            try {
                bytes= MessageDigest.getInstance("md5").digest(text.getBytes());
            }catch (NoSuchAlgorithmException e){
                log.error("没有MD5这个加密算法");
            }
//        由MD5加密算法得到的字节数组转换为16进制的数字
            StringBuilder code= new StringBuilder(new BigInteger(1,bytes).toString(16));
//        保证MD5加密后是32位
//            for(int i=0;i<32-code.length();i++){
//                code.insert(0,"0");
//            }
            return code.toString();
        }
        else{
            return null;
        }
    }

    /**
     * 字符数组拼接
     * @param data1
     * @param data2
     * @return
     */
    public static byte[] addBytes(byte[] data1, byte[] data2) {
        byte[] text = new byte[data1.length + data2.length];
        System.arraycopy(data1, 0, text, 0, data1.length);
        System.arraycopy(data2, 0, text, data1.length, data2.length);
        return text;

    }
    /**
     * 加密字符串普通不加盐
     * @param
     */
    public static String msgMD5(String text) {
        try {
            //1、生成一个MD5加密计算摘要
            MessageDigest instance = MessageDigest.getInstance("MD5");
            //2 、将消息变成byte数组
            byte[] bytes = text.getBytes();

            //3 、计算MD5加密后的16字节（128位）摘要

            byte[] buff = instance.digest();
            //4 把字节数组转换成16进制字符串
            String key = bytesToHex(buff);
            return key;
        } catch (NoSuchAlgorithmException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return "";
    }

    /**
     * 	将指定byte数组转换成16进制字符串
     * @param bytes
     * @return
     */
    public static String bytesToHex(byte[] bytes) {
        StringBuffer md5str = new StringBuffer();
        //把数组每一字节换成16进制连成md5字符串
        int digital;
        for (int i = 0; i < bytes.length; i++) {
            digital = bytes[i];

            if(digital < 0) {
                digital += 256;
            }
            if(digital < 16){
                md5str.append("0");
            }
            md5str.append(Integer.toHexString(digital));
        }
        return md5str.toString().toUpperCase();
    }
    /**
     *	 将16进制字符串转换成字节数组
     * @param hex
     * @return
     */
    public static byte[] String16ToBytes(String str) {
        if (str == null) {
            return null;
        }
        if (str.length() == 0) {
            return new byte[0];
        }
        byte[] byteArray = new byte[str.length() / 2];
        for (int i = 0; i < byteArray.length; i++) {
            String subStr = str.substring(2 * i, 2 * i + 2);
            byteArray[i] = ((byte) Integer.parseInt(subStr, 16));
        }
        return byteArray;
    }

    public static void main(String[] args) {

        //将用户名和密码的字节数组作为信息摘要转成16进制字符串并且进行MD5加密
        //将姓名作为username，学号为password
        byte[] username="余伟鹏".getBytes();
        byte[] password="19034530137".getBytes();
        //然后进行字符数组拼接
        byte[] text=addBytes(username,password);
//        进行md5加密
        String code=md5(text.toString());
        System.out.println("加密后的信息摘要是："+code);

    }
}
